﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GABLoader:IGAssetLoader {

    private string resPath = "";

    private Dictionary<string, Object> resDic = new Dictionary<string, Object>();

    private Dictionary<string, string> resInfoDic = new Dictionary<string, string>();

    private Dictionary<string, AssetBundle> abDic = new Dictionary<string, AssetBundle>();

    private Dictionary<string, ResInfo> _resDependDic = new Dictionary<string, ResInfo>();

    private AssetBundleManifest manifest;

    public GABLoader()
    {
        Init();
    }

    public void Init()
    {
        //resPath = Application.streamingAssetsPath + "/" + ApplicationPlatform.GetRunPlatform();
        //LoadMainAssetBundle();
        //string path = Application.streamingAssetsPath + "/" + ApplicationPlatform.GetRunPlatform(); //Application.dataPath + "/GResources";
        ////resInfoDic = IO.GetFilesDic(path);
        resPath = Application.persistentDataPath + "/Res/" + ApplicationPlatform.GetRunPlatform();
        LoadMainAssetBundle();
    }

    private void LoadMainAssetBundle()
     {
         string name = resPath + "/" + ApplicationPlatform.GetRunPlatform();


        //AssetBundle ab = AssetBundle.LoadFromFile(name);

        string fileName = name;//+ ".manifest";
        byte[] bytes = System.IO.File.ReadAllBytes(fileName);
        byte[] temp = IO.Decrypt(bytes, AppConfig.AB_KEY);
        AssetBundle ab = AssetBundle.LoadFromMemory(temp);


        manifest = ab.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
     }


    public T GetRes<T>(string path) where T : Object
    {
        T obj = null;
        path = path.ToLower();
        if (resDic.ContainsKey(path))
        {
            obj = resDic[path] as T;
        }
        else
        {
            string[] str = path.Split('/');
            string assetName = path.Substring(0, path.Length - str[str.Length - 1].Length - 1) + ".assetbundle";
            //assetName = assetName.ToLower();
            string resName = str[str.Length - 1];
            obj = LoadAsset<T>(assetName, resName);
            resDic.Add(path, obj);
        }
        return obj;
    }


    public Object GetRes(string path)
    {
        Object obj = null;
        path = path.ToLower();
        if (resDic.ContainsKey(path))
        {
            obj = resDic[path];
        }
        else
        {
            string[] str = path.Split('/');
            string assetName = path.Substring(0, path.Length - str[str.Length - 1].Length - 1) + ".assetbundle";
            //assetName = assetName.ToLower();
            string resName = str[str.Length - 1];
            obj = LoadAsset<Object>(assetName, resName);
            resDic.Add(path, obj);
        }
        return obj;
    }

    public void GetResAsync<T>(string path, System.Action<string, T> callback) where T : Object
    {
        path = path.ToLower();
        if(resDic.ContainsKey(path))
        {
            //obj = resDic[path] as T;
            if(callback != null)
            {
                callback(path, resDic[path] as T);
            }
        }
        else
        {
            string[] str = path.Split('/');
            string assetName = path.Substring(0, path.Length - str[str.Length - 1].Length - 1) + ".assetbundle";
            string resName = str[str.Length - 1];
            LoasAssetAsync<T>(assetName, resName, callback);
        }
    }

    public void GetResAsync(string path, System.Action<string, Object> callback)
    {
        path = path.ToLower();
        if (resDic.ContainsKey(path))
        {
            //obj = resDic[path] as T;
            if (callback != null)
            {
                callback(path, resDic[path]);
            }
        }
        else
        {
            string[] str = path.Split('/');
            string assetName = path.Substring(0, path.Length - str[str.Length - 1].Length - 1) + ".assetbundle";
            string resName = str[str.Length - 1];
            LoasAssetAsync<Object>(assetName, resName, callback);
        }
    }

    public void UnLoad(string path, bool unloadImmediately = false)
    {

    }



    /// <summary>
    /// 异步加载资源
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="path"></param>
    /// <param name="name"></param>
    /// <param name="callback"></param>
    private void LoasAssetAsync<T>(string path,string name,System.Action<string,T> callback) where T : Object
    {
        AssetBundle ab = null;
        T obj = null;
        string bundleName = path;
        path = resPath + "/" + path;
        if(abDic.ContainsKey(path))
        {
            ab = abDic[path];
            obj = ab.LoadAsset<T>(name);
            callback(bundleName, obj);
        }
        //else
        //{
        //    ResManager.instance.LoadRes(resPath + "/" + bundleName, (www) =>
        //    {
        //        ab = www.assetBundle;
        //        abDic.Add(path, ab);
        //        obj = ab.LoadAsset<T>(name);
        //        if(callback != null)
        //        {
        //            callback(bundleName, obj);
        //        }
        //    });
        //}
    }


    private T LoadAsset<T>(string path, string name) where T : Object
    {
        AssetBundle ab = null;
        T obj = null;
        string bundleName = path;
        path = resPath + "/" + path;
        if (abDic.ContainsKey(bundleName))
        {
            ab = abDic[bundleName];
        }
        else
        {
            LoadAssetBundleAndDependence(bundleName);
            //ab = AssetBundle.LoadFromFile(path);

            byte[] bytes = System.IO.File.ReadAllBytes(path);
            byte[] temp  = IO.Decrypt(bytes, AppConfig.AB_KEY);
            ab = AssetBundle.LoadFromMemory(temp);

            abDic.Add(bundleName, ab);
        }
        obj = ab.LoadAsset<T>(name);
        return obj;
    }

    /// <summary>
    /// 加载依赖
    /// </summary>
    private void LoadAssetBundleAndDependence(string assetName)
    {
        string[] dps = manifest.GetAllDependencies(assetName);
        foreach (var dp in dps)
        {
            LoadRes(dp);
        }
    }

    /// <summary>
    /// 加载依赖
    /// </summary>
    private void LoadRes(string assetName)
    {
        if (!abDic.ContainsKey(assetName))
        {
            string path = resPath + "/" + assetName;
            //AssetBundle ab = AssetBundle.LoadFromFile(path);

            byte[] bytes = System.IO.File.ReadAllBytes(path);
            byte[] temp = IO.Decrypt(bytes, AppConfig.AB_KEY);
            AssetBundle ab = AssetBundle.LoadFromMemory(temp);


            abDic.Add(assetName, ab);
            Debug.LogWarning("=========LoadDp:" + assetName);
        }
    }
}
